﻿using System;
using System.IO;
using System.Xml;

namespace AndyPike.Unfuddle.XmlEntityClassGenerator
{
    //This is just a simple quick and dirty app for generating an entity class file from the supplies 
    //Unfuddle xml data model to make live a bit easier (especially if the API changes).
    class Program
    {
        static void Main(string[] args)
        {
            /*if (args.Length != 1)
            {
                Console.WriteLine("Wrong number of arguments. You must pass only the xml file path");
                return;
            }

            string filePath = args[0];*/
            const string filePath = @"C:\OpenSource\Unfuddle.NET\src\AndyPike.Unfuddle\Entities\Tickets\ticket.xml";
            const string outputPath = @"C:\OpenSource\Unfuddle.NET\src\AndyPike.Unfuddle\Entities\Tickets\";
            Class entityClass = CreateEntityClass(filePath);
            WriteEntityClassFile(entityClass, outputPath);

            Console.WriteLine("Successfully created class: {0}", entityClass.Name);
        }

        private static void WriteEntityClassFile(Class entityClass, string outputPath)
        {
            outputPath = Path.Combine(outputPath, entityClass.Name + ".cs");
            using (var writer = new StreamWriter(outputPath))
            {
                writer.WriteLine("using System;");
                writer.WriteLine("using System.Xml.Serialization;");
                writer.WriteLine("using AndyPike.Unfuddle.Contracts;");
                writer.WriteLine("");
                writer.WriteLine("namespace AndyPike.Unfuddle.Entities.{0}s", entityClass.Name);
                writer.WriteLine("{");
                writer.WriteLine("\t/// <summary>");
                writer.WriteLine("\t/// Represents an Unfuddle {0} entity", entityClass.Name);
                writer.WriteLine("\t/// </summary>");
                writer.WriteLine("\t[XmlRoot(\"{0}\")]", entityClass.XmlName);
                writer.WriteLine("\tpublic class {0} : IEntity", entityClass.Name);
                writer.WriteLine("\t{");

                foreach (var property in entityClass.Properties)
                {
                    writer.WriteLine("\t\t/// <summary>");
                    writer.WriteLine("\t\t/// {0}", property.Info);
                    writer.WriteLine("\t\t/// </summary>");
                    writer.WriteLine("\t\t[XmlElement(\"{0}\")]", property.XmlName);
                    writer.WriteLine("\t\tpublic {0} {1} {{ get; set; }}", property.Type, property.Name);
                    writer.WriteLine("");
                }

                writer.WriteLine("\t\t/// <summary>");
                writer.WriteLine("\t\t/// Validates an Unfuddle {0} entity depending on the current validation context", entityClass.Name);
                writer.WriteLine("\t\t/// </summary>");
                writer.WriteLine("\t\tpublic virtual void Validate(EntityValidationContext context)");
                writer.WriteLine("\t\t{");
                writer.WriteLine("\t\t}");

                writer.WriteLine("\t}");
                writer.WriteLine("}");
            }
        }

        private static Class CreateEntityClass(string filePath)
        {
            var xmlDoc = new XmlDocument();
            xmlDoc.Load(filePath);

            Class entityClass = new Class(xmlDoc.DocumentElement.Name);

            foreach (XmlNode node in xmlDoc.DocumentElement.ChildNodes)
            {
                if (node.NodeType == XmlNodeType.Element)
                {
                    XmlElement element = (XmlElement)node;
                    entityClass.Properties.Add(new Property(element.Name, element.GetAttribute("type"), element.InnerText));
                }
            }
            return entityClass;
        }
    }
}
